package com.chuangjiangx.member.stored.ddd.query;

import com.chuangjiangx.commons.CJBeanUtils;
import com.chuangjiangx.commons.page.PagingResult;
import com.chuangjiangx.domain.shared.model.PayEntry;
import com.chuangjiangx.domain.shared.model.PayTerminal;
import com.chuangjiangx.domain.shared.model.PayType;
import com.chuangjiangx.member.stored.ddd.dal.dto.*;
import com.chuangjiangx.member.stored.ddd.dal.mapper.StoredStreamDalMapper;
import com.chuangjiangx.member.score.ddd.query.dto.MerchantStoredStreamListDTO;
import com.chuangjiangx.member.stored.ddd.dal.condition.QueryMerchantStoredListCondition;
import com.chuangjiangx.member.stored.ddd.dal.condition.QueryStoredCondition;
import com.chuangjiangx.member.stored.ddd.dal.condition.QueryStoredListForMerchantCondition;
import com.chuangjiangx.member.stored.ddd.dal.condition.QueryStoredStreamListCondition;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrStoredType;
import com.chuangjiangx.member.stored.ddd.dal.condition.StoredDetailForListCondition;
import com.chuangjiangx.member.stored.ddd.dal.condition.StoredValueAmountCondition;
import com.chuangjiangx.member.stored.ddd.query.dto.*;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 储值明细相关查询
 * Created by YangKuo on 2017/11/10.
 */
@Component
public class MbrStoredStreamQuery {


    @Autowired
    private StoredStreamDalMapper storedStreamDalMapper;

    /**
     * 查询储值明细列表-H5
     */
    public List<StoredStreamListForH5> searchStoredStreamListForH5(QueryStoredStreamListCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空！");


        List<StoredStreamListForH5> list = storedStreamDalMapper.queryStoredStreamListForH5(condition);

//        List<StoredDetailListDTO> respList = CJBeanUtils.convertCollection(list, StoredDetailListDTO.class, (source, target) -> {
//            if (source.getType() != null) {
//                target.setTypeText(MbrStoredType.getStoredType(source.getType()).name);
//            }
//        });

//        //按照时间维度进行分组
//        Map<Date, List<StoredDetailListDTO>> collect = respList.stream()
//                .collect(Collectors.groupingBy((Function<StoredDetailListDTO, Date>) StoredDetailListDTO::getDateTime));
//
//        //map转成所需要的对象
//        collect.forEach((date, storedDetailListDTOs) -> {
//            StoredStreamListForH5DTO h5DTO = new StoredStreamListForH5DTO();
//            h5DTO.setDateTime(date);
//            h5DTO.setStoredDetailList(storedDetailListDTOs);
//            listForH5DTOs.add(h5DTO);
//        });
//
//        //按照时间排序
//        listForH5DTOs.sort(
//                Comparator.comparingLong(o -> {
//                    StoredStreamListForH5DTO h5DTO = (StoredStreamListForH5DTO) o;
//                    return h5DTO.getDateTime().getTime();
//                }).reversed());
        return list;
    }

    /**
     * 查询储值明细列表-商户平台（储值明细报表）
     */
    public PagingResult<StoredDetailListForMerchantDTO> searchStoredListMerchant(QueryStoredListForMerchantCondition condition) {

        Assert.notNull(condition.getMerchantId(), "商户id不能为空！");
        Integer countStoredStreamListForMerchant = storedStreamDalMapper.countStoredStreamListForMerchant(condition);
        List<StoredStreamListForMerchant> list = storedStreamDalMapper.queryStoredStreamListForMerchant(condition);
        PageInfo<StoredStreamListForMerchant> pageInfo = new PageInfo<>(list);
        List<StoredDetailListForMerchantDTO> detailListForMerchantDTOs = getStoredDetailListForMerchantDTOS(list);
        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                countStoredStreamListForMerchant, detailListForMerchantDTOs);

    }

    /**
     * 查询储值明细列表-商户平台（储值明细报表 所有）
     */
    public List<StoredDetailListForMerchantDTO> searchStoredListMerchantAll(QueryStoredListForMerchantCondition condition) {

        Assert.notNull(condition.getMerchantId(), "商户id不能为空！");
        List<StoredStreamListForMerchant> list = storedStreamDalMapper.queryStoredDetailListForMerchantAll(condition);

        List<StoredDetailListForMerchantDTO> detailListForMerchantDTOs = getStoredDetailListForMerchantDTOS(list);
        return detailListForMerchantDTOs;
    }

    private List<StoredDetailListForMerchantDTO> getStoredDetailListForMerchantDTOS(List<StoredStreamListForMerchant> list) {
        List<StoredDetailListForMerchantDTO> detailListForMerchantDTOs = new ArrayList<>();

        list.forEach(storedStreamListForMerchant -> {
            StoredDetailListForMerchantDTO dto = new StoredDetailListForMerchantDTO(
                    storedStreamListForMerchant.getId(),
                    storedStreamListForMerchant.getStoredNum(),
                    storedStreamListForMerchant.getDateTime(),
                    storedStreamListForMerchant.getMobile(),
                    storedStreamListForMerchant.getType(),
                    storedStreamListForMerchant.getTransactionAmount(),
                    storedStreamListForMerchant.getGiftAmount(),
                    storedStreamListForMerchant.getAvailableBalance(),
                    storedStreamListForMerchant.getPostTradingBalance(),
                    storedStreamListForMerchant.getPayType(),
                    storedStreamListForMerchant.getStoreUserName(),
                    storedStreamListForMerchant.getPayTerminal(),
                    storedStreamListForMerchant.getPayEntry()
            );

            if (storedStreamListForMerchant.getType() != null) {
                dto.setTypeText(MbrStoredType.getStoredType(storedStreamListForMerchant.getType()).name);
            }
            if (storedStreamListForMerchant.getPayType() != null) {
                dto.setPayTypeText(PayEntry.getPayEntry(storedStreamListForMerchant.getPayEntry().intValue()).name);
            }
            if (storedStreamListForMerchant.getPayTerminal() != null) {
                dto.setPayTerminalText(PayTerminal.getPayTerminalByCode(storedStreamListForMerchant.getPayTerminal()).name);
            }

            detailListForMerchantDTOs.add(dto);
        });
        return detailListForMerchantDTOs;
    }


    /**
     * 当前会员储值明细列表-商户平台
     */
    public PagingResult<MerchantStoredStreamListDTO> searchStoredStreamListForMerchant(QueryMerchantStoredListCondition condition) {

        Assert.notNull(condition.getMerchantId(), "商户id不能为空！");
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        List<MerchantStoredStreamList> list = storedStreamDalMapper.queryMerchantStoredStreamList(condition, rowBounds);

        PageInfo<MerchantStoredStreamList> pageInfo = new PageInfo<>(list);

        List<MerchantStoredStreamListDTO> dtos = new ArrayList<>();

        list.forEach(merchantStoredStreamList -> {
            MerchantStoredStreamListDTO detailListDTO = new MerchantStoredStreamListDTO(
                    merchantStoredStreamList.getId(),
                    merchantStoredStreamList.getStoredNum(),
                    merchantStoredStreamList.getDateTime(),
                    merchantStoredStreamList.getType(),
                    merchantStoredStreamList.getTransactionAmount(),
                    merchantStoredStreamList.getGiftAmount(),
                    merchantStoredStreamList.getAvailableBalance(),
                    merchantStoredStreamList.getPostTradingBalance(),
                    merchantStoredStreamList.getStoreUserName(),
                    merchantStoredStreamList.getPayType()
            );
            if (merchantStoredStreamList.getType() != null) {
                detailListDTO.setTypeText(MbrStoredType.getStoredType(merchantStoredStreamList.getType()).name);
            }
            if (merchantStoredStreamList.getPayType() != null) {
                if (merchantStoredStreamList.getPayEntry() != null) {
                    detailListDTO.setPayTypeText(PayEntry.getPayEntry(merchantStoredStreamList.getPayEntry().intValue()).name);
                }
            }
            dtos.add(detailListDTO);
        });
        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                pageInfo.getTotal(), dtos);
    }

    /**
     * 根据id查询储值明细详情-H5
     *
     * @param id 储值明细id
     * @return
     */
    public StoredStreamInfoForH5DTO searchStoredStreamInfoForH5(Long id) {
        Assert.notNull(id, "储值明细id不能为空");
        StoredStreamInfoForH5 storedStreamInfoForH5 = storedStreamDalMapper.queryStoredStreamInfoForH5(id);

        StoredStreamInfoForH5DTO detailInfoForH5DTO = new StoredStreamInfoForH5DTO();

        //对象转换
        CJBeanUtils.convertBean(storedStreamInfoForH5, detailInfoForH5DTO, (source, target) -> {
            if (source.getType() != null) {
                target.setTypeText(MbrStoredType.getStoredType(source.getType()).name);
            }
            if (source.getPayType() != null) {
                target.setPayTypeText(PayType.getPayType(source.getPayType()).name);
            }
            if (source.getPayEntry() != null) {
                target.setPayEntryText(PayEntry.getPayEntry(source.getPayEntry().intValue()).name);
            }
        });
        return detailInfoForH5DTO;
    }

    /**
     * 会员列表-储值账户-储值明细
     *
     * @param condition
     * @return StoredDetailForListDTO
     */
    public PagingResult<StoredDetailForListDTO> queryStoredStreamForList(StoredDetailForListCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空！");

        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());

        List<StoredStreamForList> list = storedStreamDalMapper.queryStoredDetailForList(condition, rowBounds);
        PageInfo<StoredStreamForList> pageInfo = new PageInfo<>(list);

        List<StoredDetailForListDTO> listDTOS = CJBeanUtils.convertCollection(list, StoredDetailForListDTO.class, (source, target) -> {
            if (source.getType() != null) {//交易类型转换
                target.setTypeText(MbrStoredType.getStoredType(source.getType()).name);
            }
            if (source.getPayEntry() != null) {//转换支付方式
                target.setPayEntryText(PayEntry.getPayEntry(source.getPayEntry().intValue()).name);
            }
            if (source.getStoreId() == null) {//自助充值时候门店为空 门店显示商户用户名称
                target.setStoreName(source.getMerchantUserName());
            }
        });
        return new PagingResult<>(pageInfo.getPageNum(), pageInfo.getPageNum(), pageInfo.getTotal(), listDTOS);
    }

    /**
     * 会员列表-储值账户-根据会员id查询储值
     *
     * @param condition 参数
     * @return StoredValueAmountDTO
     */
    public StoredValueAmountDTO queryStoredValueByMemberIdAndMerchant(StoredValueAmountCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        StoredValueAmount storedValueAmount = storedStreamDalMapper.queryStoredValueByMemberIdAndMerchant(condition);
        StoredValueAmountDTO storedValueAmountDTO = new StoredValueAmountDTO();
        CJBeanUtils.convertBean(storedValueAmount, storedValueAmountDTO);
        return storedValueAmountDTO;
    }

    /**
     * 储值明细报表，金额统计
     *
     * @param condition 参数
     * @return StoredAmountDTO
     */
    public StoredAmountDTO searchStoredAmount(QueryStoredCondition condition) {

        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        StoredAmountDTO dto = new StoredAmountDTO();

        //历史储值
        BigDecimal hisStoredAmount = storedStreamDalMapper.queryHisStoredAmount(condition);
        //历史消费
        BigDecimal hisConsumeAmount = storedStreamDalMapper.queryHisConsumeAmount(condition);
        //历史退款
        BigDecimal hisRefundAmount = storedStreamDalMapper.queryHisRefundAmount(condition);
        //历史赠送金额
        BigDecimal hisGiftAmount = storedStreamDalMapper.queryHisGiftAmount(condition);

        //总储值
        dto.setActualAmount(hisStoredAmount == null ?
                new BigDecimal(0.00) : hisStoredAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
        //赠送总额
        dto.setGiftAmount(hisGiftAmount == null ?
                new BigDecimal(0.00) : hisGiftAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
        //消费扣款
        dto.setUsedAmount(hisConsumeAmount == null ?
                new BigDecimal(0.00) : hisConsumeAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
        //退款退回金额
        dto.setRefundAmount(hisRefundAmount == null ?
                new BigDecimal(0.00) : hisRefundAmount.setScale(2, BigDecimal.ROUND_HALF_UP));

        //历史储值
        dto.setHisStoredAmount(hisStoredAmount == null ?
                new BigDecimal(0.00) : hisStoredAmount.add(hisGiftAmount == null ?
                new BigDecimal(0.00) : hisGiftAmount).setScale(2, BigDecimal.ROUND_HALF_UP));

        ////历史消耗
        dto.setUsedHisAmount(hisConsumeAmount == null ?
                new BigDecimal(0.00) : hisConsumeAmount.subtract(hisRefundAmount == null ?
                new BigDecimal(0.00) : hisRefundAmount).setScale(2, BigDecimal.ROUND_HALF_UP));

        //历史结余
        dto.setResuletAmount(hisStoredAmount == null ?
                new BigDecimal(0.00) : hisStoredAmount.subtract(hisConsumeAmount == null ?
                new BigDecimal(0.00) : hisConsumeAmount).add(hisRefundAmount == null ?
                new BigDecimal(0.00) : hisRefundAmount).add(hisGiftAmount == null ?
                new BigDecimal(0.00) : hisGiftAmount).setScale(2, BigDecimal.ROUND_HALF_UP));

        return dto;
    }

    /**
     * @param mbrOrderId
     * @return
     */
    public StoredStreamDTO queryByMbrOrderIdAndType(Long mbrOrderId, MbrStoredType type){
        return storedStreamDalMapper.selectByMbrOrderIdAndType(mbrOrderId,type.value);
    }
}
